package com.bill99.testmp.testautomation.mdp.service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.util.StringUtils;

import com.bill99.riaframework.common.dto.NotifyTaResultClassMethodDto;
import com.bill99.rmca.common.util.Bill99Logger;
import com.bill99.testmp.ta.mdp.api.common.TaNotifyMessage;
import com.bill99.testmp.ta.mdp.api.common.TaResultMessage;
import com.bill99.testmp.ta.mdp.api.service.TaReportService;
import com.bill99.testmp.testmanage.common.utils.TaUtils;
import com.bill99.testmp.testmanage.domain.TaTaskNotifier;
import com.bill99.testmp.testmanage.orm.entity.AssoTaTaskMethod;
import com.bill99.testmp.testmanage.orm.entity.TaBuild;
import com.bill99.testmp.testmanage.orm.entity.TaResult;
import com.bill99.testmp.testmanage.orm.entity.TaTask;
import com.bill99.testmp.testmanage.orm.ibatis.dto.CaseStateDto;
import com.bill99.testmp.testmanage.orm.manager.AssoTaTaskMethodMng;
import com.bill99.testmp.testmanage.orm.manager.TaBuildMng;
import com.bill99.testmp.testmanage.orm.manager.TaMng;
import com.bill99.testmp.testmanage.orm.manager.TaResultMng;
import com.bill99.testmp.testmanage.orm.manager.TaTaskMng;

public class TaReportCollector implements TaReportService {
	private final Bill99Logger logger = Bill99Logger.getLogger(this.getClass());

	private TaBuildMng taBuildMng;
	private TaResultMng taResultMng;
	private TaMng taMng;
	private AssoTaTaskMethodMng assoTaTaskMethodMng;
	private TaTaskMng taTaskMng;
	private TaTaskNotifier taTaskNotifier;

	public void notifyTaLaunch(TaNotifyMessage taNotifyMessage) {

		String jobName = taNotifyMessage.getJobName();
		String buildId = taNotifyMessage.getBuildId();
		String buildNumber = taNotifyMessage.getBuildNumber();
		String idTaTask = taNotifyMessage.getIdTaTask();

		logger.info("===###=> message		invalid @" + jobName + " | " + buildId + " | " + buildNumber + " | " + idTaTask + " | " + "	<=###===");

		if (!StringUtils.hasLength(jobName) || !StringUtils.hasLength(buildId) || !StringUtils.hasLength(buildNumber) || !StringUtils.hasLength(idTaTask)) {
			logger.info("taNotifyMessage invalid");
			return;
		}

		String memo = taNotifyMessage.getMemo();
		String errorMsg = taNotifyMessage.getErrorMsg();

		TaBuild taBuild = null;
		if (taNotifyMessage.getType()) {//任务开始
			taBuild = new TaBuild();
			taBuild.setJobName(jobName);
			taBuild.setBuildId(buildId);
			taBuild.setBuildNum(buildNumber);
			taBuild.setIdTaTask(Long.valueOf(idTaTask));
			taBuild.setMemo(memo);
			taBuild.setErrorMsg(errorMsg);
			taBuild.setState(TaUtils.BUILD_STATE_ING);//构建结果
			taBuildMng.save(taBuild);
		} else {//任务结束
			taBuild = taBuildMng.query4rp(jobName, buildId, buildNumber);
			taBuild.setFinishDate(new Date());
			//			taBuild.setState(taMng.isSuccess(taBuild.getIdBuild()) == true ? TaUtils.BUILD_STATE_PASS : TaUtils.BUILD_STATE_FAIL);//构建结果
			taBuild.setState(TaUtils.BUILD_STATE_PASS);//构建结果
			taBuildMng.update(taBuild);
			//回填测试结果

			TaTask taTask = taTaskMng.getTaTask(Long.valueOf(idTaTask));
			if (taTask != null) {
				taMng.updatePlanTc(Long.valueOf(idTaTask), taTask.getPlanStepId());//更新测试影响的TC
				CaseStateDto caseStateDto = taMng.getCaseState(taTask.getPlanStepId());
				caseStateDto.setTaTaskId(taTask.getTaTaskId());
				caseStateDto.setPlanStepId(taTask.getPlanStepId());
				caseStateDto.setUpdateDate(new Date());
				taMng.updateCaseState(caseStateDto);

				//通知
				taTaskNotifier.taTaskEmailReport(taTask.getTaTaskId(), taTask.getPlanStepId(), taTask.getTestProjectId());

			} else {
				logger.info("taTask: " + idTaTask + "  is not exist! ");
			}
		}

	}

	public void notifyTaResult(TaResultMessage taResultMessage) {

		TaBuild taBuild = getTaBuild(taResultMessage);

		logger.info("===###=> result		trigger @" + taBuild.getJobName() + " | " + taBuild.getBuildId() + " | " + taBuild.getBuildNum() + " | " + taBuild.getIdTaTask() + " | "
				+ "		<=###===");

		if (taBuild != null && taBuild.getIdMethod() != null) {
			TaResult taResult = new TaResult();
			taResult.setErrorMsg(taResultMessage.getErrorMsg());
			taResult.setIdBuild(taBuild.getIdBuild());
			taResult.setMemo(taResultMessage.getMemo());
			taResult.setIdSvnMethod(taBuild.getIdMethod());
			taResult.setState(taResultMessage.getResult());
			taResult.setType(taResultMessage.getType());
			taResultMng.save(taResult);
		}

	}

	public void setTaBuildMng(TaBuildMng taBuildMng) {
		this.taBuildMng = taBuildMng;
	}

	public void setTaResultMng(TaResultMng taResultMng) {
		this.taResultMng = taResultMng;
	}

	public void setTaMng(TaMng taMng) {
		this.taMng = taMng;
	}

	public void notifyTaInvokedMethod(TaResultMessage taResultMessage) {

		TaBuild taBuild = getTaBuild(taResultMessage);

		logger.info("===###=> invokedMethod	trigger	@" + taBuild.getJobName() + " | " + taBuild.getBuildId() + " | " + taBuild.getBuildNum() + " | " + taBuild.getIdTaTask()
				+ " | " + "		<=###===");

		if (taBuild != null && taBuild.getIdMethod() != null) {
			boolean newFlag = false;
			AssoTaTaskMethod assoTaTaskMethod = assoTaTaskMethodMng.getById(Long.valueOf(taResultMessage.getIdTaTask()), taBuild.getIdMethod());
			if (assoTaTaskMethod == null) {
				assoTaTaskMethod = new AssoTaTaskMethod();
				newFlag = true;
			}

			assoTaTaskMethod.setIdSvnMethod(taBuild.getIdMethod());
			assoTaTaskMethod.setIdTaTask(Long.valueOf(taResultMessage.getIdTaTask()));
			assoTaTaskMethod.setCostMillis(taResultMessage.getCostMillis());

			if (taResultMessage.getException() != null && StringUtils.hasLength(taResultMessage.getException().getMessage())) {
				StringBuilder errorMsgSb = new StringBuilder();
				errorMsgSb.append(taResultMessage.getException().getMessage().toString());
				errorMsgSb.append("\n\t");
				for (StackTraceElement element : taResultMessage.getException().getStackTrace()) {
					errorMsgSb.append(element.toString());
					errorMsgSb.append("\n\t");
				}
				assoTaTaskMethod.setErrorMsg(assoTaTaskMethod.getErrorMsg() + "\n\t" + errorMsgSb.toString());
				assoTaTaskMethod.setState(Boolean.FALSE);
			} else {
				if (assoTaTaskMethod.getState() == null) {
					assoTaTaskMethod.setState(Boolean.TRUE);
				}
			}

			if (newFlag) {
				assoTaTaskMethodMng.save(assoTaTaskMethod);
			} else {
				assoTaTaskMethodMng.update(assoTaTaskMethod);
			}
		}

	}

	private TaBuild getTaBuild(TaResultMessage message) {

		TaBuild taBuild = new TaBuild();

		String idTaTask = message.getIdTaTask();
		String jobName = message.getJobName();
		String buildId = message.getBuildId();
		String buildNumber = message.getBuildNumber();
		String errorMsg = message.getErrorMsg();
		String memo = message.getMemo();
		Integer state = message.getState();

		if (!StringUtils.hasLength(jobName) || !StringUtils.hasLength(buildId) || !StringUtils.hasLength(buildNumber) || !StringUtils.hasLength(idTaTask)) {
			logger.info("taResultMessage invalid");
			return taBuild;
		}

		String taProjectName = message.getTaProjectName();
		String taMethodName = message.getTaMethodName();

		NotifyTaResultClassMethodDto notifyTaResultClassMethodDto = new NotifyTaResultClassMethodDto();
		Long idTaProject = taBuildMng.getIdTaProject(Long.valueOf(idTaTask), jobName);
		if (idTaProject == null) {
			logger.info("taTask: " + idTaTask + "  is not exist! ");
			return taBuild;
		}

		StringBuilder packageNameBd = new StringBuilder();
		String taClassName = "";
		String packageName = "";
		String[] pNames = taProjectName.split("\\.");
		if (pNames.length > 1) {
			for (int i = 0; i < pNames.length; i++) {
				if (i < pNames.length - 1) {
					packageNameBd.append(pNames[i]);
					packageNameBd.append(".");
				} else {
					taClassName = pNames[i];
				}
			}
		} else {
			taClassName = pNames[0];
		}
		if (packageNameBd.length() > 0) {
			packageName = packageNameBd.toString();
			packageName = packageName.substring(0, packageName.length() - 1);
		}
		notifyTaResultClassMethodDto.setTaClassName(taClassName);
		notifyTaResultClassMethodDto.setPackageName(packageName);

		Map paramMap = new HashMap();
		paramMap.put("methodName", taMethodName);
		paramMap.put("className", notifyTaResultClassMethodDto.getTaClassName());
		paramMap.put("idTaProject", idTaProject.toString());
		paramMap.put("packageName", notifyTaResultClassMethodDto.getPackageName());
		Long idMethod = taMng.getTaMethodId(paramMap);

		taBuild = taBuildMng.query4rp(jobName, buildId, buildNumber);
		taBuild.setIdMethod(idMethod);
		return taBuild;

	}

	//		System.out.println("getJobName::" + taResultMessage.getJobName());
	//		System.out.println("getBuildId::" + taResultMessage.getBuildId());
	//		System.out.println("getBuildNumber::" + taResultMessage.getBuildNumber());
	//		System.out.println("getErrorMessage::" + taResultMessage.getErrorMessage());
	//		System.out.println("getMemo::" + taResultMessage.getMemo());
	//		System.out.println("getTaClassName::" + taResultMessage.getTaClassName());
	//		System.out.println("getTaMethodName::" + taResultMessage.getTaMethodName());
	//		System.out.println("getTaProjectName::" + taResultMessage.getTaProjectName());
	//		System.out.println("getTestCaseSn::" + taResultMessage.getTestCaseSn());
	//		System.out.println("getResultStatus::" + taResultMessage.getResultStatus());
	//		System.out.println("getTestPlanId::" + taResultMessage.getTestPlanId());
	//		System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");

	public void setAssoTaTaskMethodMng(AssoTaTaskMethodMng assoTaTaskMethodMng) {
		this.assoTaTaskMethodMng = assoTaTaskMethodMng;
	}

	public void setTaTaskMng(TaTaskMng taTaskMng) {
		this.taTaskMng = taTaskMng;
	}

	public void setTaTaskNotifier(TaTaskNotifier taTaskNotifier) {
		this.taTaskNotifier = taTaskNotifier;
	}

}